// 获得一个 1 或者 0 的随机数
const random01 = function() {
    let n = Math.random()
    n = n * 10
    n = Math.floor(n)
    return n % 2
}

//返回一个只包含了 0 和 9 的随机 array, 长度为 n
const randomLine = function(n) {
    let l = []
    for (let i = 0; i < n; i++) {
        let r = random01() * 9
        l.push(r)
    }
    return l
}

const arrayTOSquare = (array) => {
    let n = Math.sqrt(array.length)
    let square = []
    for (let i = 0; i < array.length; i = i + n) {
        let line = []
        for (let j = 0; j < n; j++) {
            line.push(array[i + j])
        }
        square.push(line)
    }
    return square
}

const arrayClone = function(array) {
    let a2 = []
    for (let i = 0; i < array.length; i++) {
        a2.push(array[i])
    }
    return a2
}

const check = (array) => {
    let mode = e('.mode')
    let limit = Number(mode.dataset.limit)
    let num = 0
    let a = arrayClone(array)
    for (let i = 0; i < a.length; i++) {
        if (a[i] === 9) {
            num += 1
            if (num > limit) {
                a[i] = 0
            }
        }
    }
    return a
}

//洗牌
const shuffle = (array) => {
    const length = array == null ? 0 : array.length
    if (!length) {
        return []
    }
    let index = -1
    const lastIndex = length - 1
    const result = arrayClone(array)
    while (++index < length) {
        const rand = index + Math.floor(Math.random() * (lastIndex - index + 1))
        const value = result[rand]
        result[rand] = result[index]
        result[index] = value
    }
    return result
}

const clonedSquare = function(array) {
    let l = []
    for (let i = 0; i < array.length; i++) {
        let line = array[i]
        let c = line.slice(0)
        l.push(c)
    }
    return l
}

const plus1 = function(array, x, y) {
    let n = array.length
    if (x >= 0 && x < n && y >= 0 && y < n) {
        if (array[x][y] !== 9) {
            array[x][y] += 1
        }
    }
}

const markAround = function(array, x, y) {
    if (array[x][y] === 9) {
        plus1(array, x - 1, y - 1)
        plus1(array, x, y - 1)
        plus1(array, x + 1, y - 1)

        plus1(array, x - 1, y)
        plus1(array, x + 1, y)

        plus1(array, x - 1, y + 1)
        plus1(array, x, y + 1)
        plus1(array, x + 1, y + 1)
    }
}

const createSquare = function() {
    let array = arrayTOSquare(shuffle(check(randomLine(81))))
    let square = clonedSquare(array)
    for (let i = 0; i < square.length; i++) {
        let line = square[i]
        for (let j = 0; j < line.length; j++) {
            markAround(square, i, j)
        }
    }
    return square
}

const templateCell = (line, x) => {
    let s = ''
    for (let i = 0; i < line.length; i++) {
        s += `<td class="cell backgrounded" data-number="${line[i]}" data-x="${String(x)}" data-y="${String(i)}">${line[i]}</td>`
    }
    return s
}

const templateRow = function(square) {
    let s = ''
    for (let i = 0; i < square.length; i++) {
        s += `<tr>${templateCell(square[i], i)}</tr>`
    }
    return s
}

const renderSquare = function(square) {
    let div = e('.mine-body')
    div.innerHTML = templateRow(square)
}

const bindEventDelegate = function(square) {
    bindAll('.cell', 'click', function(event) {
        let self = event.target
        if (closestClass(self, 'gameover') === null) {
            update(self, square)
        }
        decision()
    })
    bindFlag()
}

const update = function(self, square) {
    let cell = self
    let cells = es('.cell')
    let isFirst = true
    for (let c of cells) {
        if (c.classList.contains('opened') || c.classList.contains('flag')) {
            isFirst = false
        }
    }
    if (isFirst) {
        let num = Number(self.dataset.number)
        let x = self.dataset.x
        let y = self.dataset.y
        while (num === 9) {
            log('in')
            resetGame()
            let index = `[data-x="${x}"][data-y="${y}"]`
            cell = e(index)
            num = Number(cell.dataset.number)
        }
    }
    vjkl(cell, square)
}

const vjkl = function(cell, square) {
    if (!cell.classList.contains('opened') && !cell.classList.contains('flag')) {
        let num = Number(cell.dataset.number)
        cell.classList.add('opened')
        if (num === 9) {
            let container = cell.parentElement.parentElement
            container.classList.add('gameover')
            let over = es('[data-number="9"]')
            for (let overN of over) {
                overN.classList.add('opened')
                overN.classList.add('bomb')
                overN.classList.remove('flag')
            }
        } else if (num === 0) {
            cell.classList.add('space')
            let x = Number(cell.dataset.x)
            let y = Number(cell.dataset.y)
            vjklAround(square, x, y)
        }
    }
}

const vjklAround = function(square, x, y) {
    if (square[x][y] === 0) {
        vjkl1(square, x - 1, y - 1)
        vjkl1(square, x, y - 1)
        vjkl1(square, x + 1, y - 1)

        vjkl1(square, x - 1, y)
        vjkl1(square, x + 1, y)

        vjkl1(square, x - 1, y + 1)
        vjkl1(square, x, y + 1)
        vjkl1(square, x + 1, y + 1)
    }
}

const vjkl1 = function(square, x, y) {
    let x1 = Number(x)
    let y1 = Number(y)
    if (x1 >= 0 && x1 < square[0].length && y1 >= 0 && y1 < square.length) {
        let index = `[data-x="${x1}"][data-y="${y1}"]`
        let cell = e(index)
        let num = Number(cell.dataset.number)
        if (!cell.classList.contains('opened')) {
            if (num === 0) {
                cell.classList.add('opened')
                cell.classList.add('space')
                cell.classList.remove('flag')
                vjklAround(square, x1, y1)
            } else if (num !== 9) {
                cell.classList.add('opened')
                cell.classList.remove('flag')
            }
        }
    }
}

